# -*- coding:utf-8 -*-
# @FileName : app\services\mcp_server\mcp_service.py
# @Time     : 2025/11/28
# @Author   : 天空之城
"""
MCP Service 服务类
提供对 MCP 工具的统一调用接口，处理截图和日志记录等功能
"""
#!/usr/bin/env python3
# -*- coding: utf-8 -*-



import json
import base64
from typing import Any, Dict, Optional, List
from app.services.mcp_server.mcp_client import MCPClient
from app.utils.file_handler import save_screenshot_from_base64
from app.config import logger


class MCPService:
    """MCP服务类，封装MCP工具调用逻辑"""

    def __init__(self, server_url: str):
        """
        初始化MCP服务
        Args:
            server_url (str): MCP服务器URL
        """
        self.server_url = server_url
        self.client = MCPClient(server_url)
        self.task_id = None
        logger.info(f"MCPService 初始化完成，服务器地址: {server_url}")

    async def connect(self):
        """连接到MCP服务器"""
        try:
            await self.client.connect()
            logger.info(f"MCPService 连接成功: {self.server_url}")
        except Exception as e:
            logger.error(f"MCPService 连接失败: {self.server_url}, 错误: {str(e)}")
            raise

    async def disconnect(self):
        """断开与MCP服务器的连接"""
        try:
            await self.client.disconnect()
            logger.info(f"MCPService 断开连接: {self.server_url}")
        except Exception as e:
            logger.error(f"MCPService 断开连接失败: {self.server_url}, 错误: {str(e)}")
            # 不抛出异常，以免影响主流程关闭

    async def get_available_tools_schema(self) -> List[Dict[str, Any]]:
        """
        动态获取所有可用工具，并转换为 OpenAI Function Calling 格式
        这是实现"智能执行"的关键，不再需要硬编码 JSON。
        """
        try:
            # 假设 client.list_tools() 返回 MCP 协议标准的工具列表对象
            result = await self.client.list_tools()
            tools = result.tools

            openai_tools = []
            for tool in tools:
                openai_tools.append({
                    "type": "function",
                    "function": {
                        "name": tool.name,
                        "description": tool.description,
                        "parameters": tool.inputSchema  # MCP Schema 通常直接兼容 JSON Schema
                    }
                })

            # 注入 finish_task 工具定义
            finish_task_tool = {
                "type": "function",
                "function": {
                    "name": "finish_task",
                    "description": "调用此工具以结束任务，当任务已完成或无法继续执行时使用",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "reason": {
                                "type": "string",
                                "description": "结束任务的原因"
                            },
                            "result": {
                                "type": "string",
                                "description": "任务执行结果"
                            }
                        },
                        "required": ["reason"]
                    }
                }
            }
            openai_tools.append(finish_task_tool)

            logger.info(f"成功加载 {len(openai_tools)} 个 MCP 工具定义")
            return openai_tools
        except Exception as e:
            logger.error(f"获取 MCP 工具列表失败: {str(e)}")
            return []

    async def execute_tool(self, tool_name: str, params: Dict[str, Any], task_id: Optional[str] = None) -> Dict[
        str, Any]:
        """
        执行MCP工具调用
        Args:
            tool_name (str): 工具名称
            params (Dict[str, Any]): 工具参数
            task_id (Optional[str]): 任务ID
        """
        self.task_id = task_id

        try:
            logger.info(f"[MCP工具调用] 工具: {tool_name}, 参数: {params}, 任务ID: {task_id}")

            # 调用MCP工具
            result = await self.client.call_tool(tool_name, params)

            logger.info(f"[MCP工具调用成功] 工具: {tool_name}，参数{params}")
            return result

        except Exception as e:
            logger.error(f"[MCP工具调用失败] 工具: {tool_name}, 错误: {str(e)}")
            raise

    async def _process_result(self, result: Any) -> Dict[str, Any]:
        """处理工具执行结果，特别处理截图数据"""
        pass
        return None

    async def assert_condition(self, prompt: str, expected_keywords: list) -> Dict[str, Any]:
        """断言条件，验证屏幕内容是否符合预期"""
        try:
            pass
        except Exception as e:
            logger.error(f"[断言验证失败] 错误: {str(e)}")
            raise

    async def __aenter__(self):
        await self.connect()
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        await self.disconnect()
